package com.xiaoyudeguang.wrapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xiaoyudeguang.context.SpringContext;
import com.xiaoyudeguang.mapper.BaseMapperImpl;

import java.util.Collection;
import java.util.function.Consumer;

/**
 * @author 赵光
 */
public class StreamQueryWrapper<T> extends BaseMapperImpl<QueryWrapper<T>, T> {

    public StreamQueryWrapper(Class<T> entityClass) {
        this(new QueryWrapper<T>(entityClass), null);
    }

    public StreamQueryWrapper(QueryWrapper<T> wrapper) {
        this(wrapper, null);
    }

    public StreamQueryWrapper(BaseMapper<T> baseMapper) {
        this(new QueryWrapper<T>(), baseMapper);
    }

    public StreamQueryWrapper(QueryWrapper<T> wrapper, BaseMapper<T> baseMapper) {
        super(wrapper, baseMapper);
    }

    /**
     * 等于
     */
    public StreamQueryWrapper<T> eq(String column, Object value) {
        this.wrapper.eq(column, value);

        return this;
    }

    /**
     * 等于
     */
    public StreamQueryWrapper<T> eq(boolean condition, String column, Object value) {
        return !condition ? this : eq(column, value);
    }

    /**
     * 不等于
     */
    public StreamQueryWrapper<T> ne(String column, Object value) {
        this.wrapper.ne(column, value);
        return this;
    }

    /**
     * 不等于
     */
    public StreamQueryWrapper<T> ne(boolean condition, String column, Object value) {
        return !condition ? this : ne(column, value);
    }

    /**
     * 大于
     */
    public StreamQueryWrapper<T> gt(String column, Object value) {
        this.wrapper.gt(column, value);
        return this;
    }

    /**
     * 大于
     */
    public StreamQueryWrapper<T> gt(boolean condition, String column, Object value) {
        return !condition ? this : gt(column, value);
    }

    /**
     * 大于等于
     */
    public StreamQueryWrapper<T> ge(String column, Object value) {
        this.wrapper.ge(column, value);
        return this;
    }

    /**
     * 大于等于
     */
    public StreamQueryWrapper<T> ge(boolean condition, String column, Object value) {
        return !condition ? this : ge(column, value);
    }

    /**
     * 小于
     */
    public StreamQueryWrapper<T> lt(String column, Object value) {
        this.wrapper.lt(column, value);
        return this;
    }

    /**
     * 小于
     */
    public StreamQueryWrapper<T> lt(boolean condition, String column, Object value) {
        return !condition ? this : lt(column, value);
    }

    /**
     * 小于等于
     */
    public StreamQueryWrapper<T> le(String column, Object value) {
        this.wrapper.le(column, value);
        return this;
    }

    /**
     * 小于等于
     */
    public StreamQueryWrapper<T> le(boolean condition, String column, Object value) {
        return !condition ? this : le(column, value);
    }

    /**
     * 模糊匹配
     */
    public StreamQueryWrapper<T> like(String column, Object value) {
        this.wrapper.like(column, value);
        return this;
    }

    /**
     * 模糊匹配
     */
    public StreamQueryWrapper<T> like(boolean condition, String column, Object value) {
        return !condition ? this : like(column, value);
    }

    /**
     * 反向模糊匹配
     *
     * @return
     */
    public StreamQueryWrapper<T> notLike(String column, Object value) {
        this.wrapper.notLike(column, value);
        return this;
    }

    /**
     * 反向模糊匹配
     *
     * @return
     */
    public StreamQueryWrapper<T> notLike(boolean condition, String column, Object value) {
        return !condition ? this : notLike(column, value);
    }


    /**
     * 向右模糊匹配
     */
    public StreamQueryWrapper<T> likeRight(String column, Object value) {
        this.wrapper.likeRight(column, value);
        return this;
    }

    /**
     * 向右模糊匹配
     */
    public StreamQueryWrapper<T> likeRight(boolean condition, String column, Object value) {
        return !condition ? this : likeRight(column, value);
    }

    /**
     * 向左模糊匹配
     */
    public StreamQueryWrapper<T> likeLeft(String column, Object value) {
        this.wrapper.likeLeft(column, value);
        return this;
    }

    /**
     * 向左模糊匹配
     */
    public StreamQueryWrapper<T> likeLeft(boolean condition, String column, Object value) {
        return !condition ? this : likeLeft(column, value);
    }

    /**
     * 存在
     */
    public StreamQueryWrapper<T> exists(String column) {
        this.wrapper.isNotNull(column);
        return this;
    }

    /**
     * 存在
     */
    public StreamQueryWrapper<T> exists(boolean condition, String column) {
        return !condition ? this : exists(column);
    }

    /**
     * 存在
     *
     * @return
     */
    public StreamQueryWrapper<T> in(String column, Object... values) {
        this.wrapper.in(column, values);
        return this;
    }

    /**
     * 存在
     *
     * @return
     */
    public StreamQueryWrapper<T> in(boolean condition, String column, Object... values) {
        return !condition ? this : in(column, values);
    }

    /**
     * 存在
     *
     * @return
     */
    public StreamQueryWrapper<T> in(String column, Collection<?> values) {
        this.wrapper.in(column, values);
        return this;
    }

    /**
     * 存在
     *
     * @return
     */
    public StreamQueryWrapper<T> in(boolean condition, String column, Collection<?> values) {
        return !condition ? this : in(column, values);
    }

    /**
     * 不存在
     *
     * @return
     */
    public StreamQueryWrapper<T> notIn(String column, Object... values) {
        this.wrapper.notIn(column, values);
        return this;
    }

    /**
     * 不存在
     *
     * @return
     */
    public StreamQueryWrapper<T> notIn(boolean condition, String column, Object... values) {
        return !condition ? this : lt(column, values);
    }

    /**
     * 不存在
     *
     * @return
     */
    public StreamQueryWrapper<T> notIn(String column, Collection<?> values) {
        this.wrapper.notIn(column, values);
        return this;
    }

    /**
     * 不存在
     *
     * @return
     */
    public StreamQueryWrapper<T> notIn(boolean condition, String column, Collection<?> values) {
        return !condition ? this : lt(column, values);
    }

    /**
     * 区间
     *
     * @return
     */
    public StreamQueryWrapper<T> between(String column, Object... values) {
        this.wrapper.between(column, values[0], values[1]);
        return this;
    }

    /**
     * 区间
     *
     * @return
     */
    public StreamQueryWrapper<T> between(boolean condition, String column, Object... values) {
        return !condition ? this : between(column, values);
    }

    /**
     * 为空
     */
    public StreamQueryWrapper<T> isNull(String column) {
        this.wrapper.isNull(column);
        return this;
    }

    /**
     * 为空
     */
    public StreamQueryWrapper<T> isNull(boolean condition, String column) {
        return !condition ? this : isNull(column);
    }

    /**
     * 不为空
     */
    public StreamQueryWrapper<T> isNotNull(String column) {
        this.wrapper.isNotNull(column);
        return this;
    }

    /**
     * 不为空
     */
    public StreamQueryWrapper<T> isNotNull(boolean condition, String column) {
        return !condition ? this : isNotNull(column);
    }

    /**
     * 等于
     */
    public StreamQueryWrapper<T> or() {
        this.wrapper.or();
        return this;
    }

    /**
     * 或条件拼接
     */
    public StreamQueryWrapper<T> and(Consumer<StreamQueryWrapper<T>> consumer) {
        StreamQueryWrapper<T> streamQueryWrapper = new StreamQueryWrapper<>(this.wrapper);
        consumer.accept(streamQueryWrapper);
        return this;
    }

    public StreamLambdaQueryWrapper lambda() {
        return new StreamLambdaQueryWrapper<T>(wrapper.lambda(), baseMapper);
    }

    @Override
    public BaseMapper<T> getMapper() {
        if (baseMapper != null) {
            return baseMapper;
        }
        if (wrapper.getEntityClass() == null) {
            throw new RuntimeException("请设置实体类");
        }
        return (BaseMapper<T>) SpringContext.getContext().getBean(StringUtils.firstToLowerCase(wrapper.getEntityClass().getSimpleName() + "Mapper"));
    }
    
}
